﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Zarzadzanie_Restautacja.Helpers;
using Zarzadzanie_Restautacja.Model;

namespace Zarzadzanie_Restautacja.Controllers
{
    public class Obsluga : DbObject, IPracownik
    {
        #region Properties

        public int Id { get; set; }
        public string Imie { get; set; }
        public string Nazwisko { get; set; }
        public int Funkcja
        {
            get { return (int)Funkcje.Obsluga; }
            set { }
        }
        public string Haslo { get; set; }

        public Funkcje FunkcjaEnum
        {
            get { return (Funkcje)this.Funkcja; }
            set { this.Funkcja = (int)Funkcje.Obsluga; }
        }

        #endregion Properties

        #region Methods

        /// <summary>
        /// Tworzy zamówienie, dodaje potrawy do zamówienia poprzez dodanie rekordów w tabeli ZamowieniaPotrawy
        /// </summary>
        /// <param name="potrawy">Potrawy do dodania</param>
        /// <param name="nrStolika">Stolik składajacy zamówienie</param>
        /// <returns>Dodane zamówienie</returns>
        public Zamowienie StworzZamowienie(List<Potrawa> potrawy, int nrStolika)
        {
            try
            {
                using (RestauracjaContext context = new RestauracjaContext())
                {
                    Zamowienie zamowienie = new Zamowienie()
                    {
                        Id = Zamowienie.PobierzWolneId(),
                        NrStolika = nrStolika,
                        Status = (int)Status.Przyjete,
                        data = DateTime.Now,
                        Cena = (decimal)potrawy.Sum(potr => potr.Cena)
                    };

                    context.Zamowienia.Add(zamowienie);

                    foreach (var potrawa in potrawy)
                    {
                        ZamowieniaPotrawy zampotr = new ZamowieniaPotrawy();
                        zampotr.Id = ZamowieniaPotrawy.PobierzWolneId(context);
                        zampotr.CzyWydana = (int)ZamowieniePotrawaStatus.KelnerZlecilDoKuchni;
                        //zampotr.CzyWydana = (int)ZamowieniePotrawaStatus.KuchniaZlecilaDoKelnera;
                        zampotr.IdPotrawy = potrawa.Id;
                        zampotr.IdZamowienia = zamowienie.Id;
                        context.ZamowieniaPotrawy.Add(zampotr);
                    }

                    context.SaveChanges();
                    return zamowienie;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Wystapił błąd przy tworzeniu zamówienia");
                return null;
            }
        }

        /// <summary>
        /// Edytuje Status zamówienia
        /// </summary>
        /// <param name="zamowienie">Zamówienie do edycji</param>
        /// <param name="status">Status na jaki ma być zmienione</param>
        public void EdytujStatusZamowienie(Zamowienie zamowienie, Status status)
        {
            try
            {
                using (RestauracjaContext context = new RestauracjaContext())
                {
                    //Wszystkie propertiesy są przypisywane- inaczej nie działa update :(
                    var zamowie = context.Zamowienia.Where(zam => zam.Id == zamowienie.Id).First();
                    zamowie.Status = (int)status;
                    zamowie.Cena = zamowienie.Cena;
                    zamowie.data = zamowienie.data;
                    zamowie.NrStolika = zamowienie.NrStolika;
                    zamowie.Id = zamowienie.Id;

                    context.SaveChanges();
                }
            }
            catch (Exception)
            {
                MessageBox.Show("Wystapił błąd przy zmianie statusu zamówienia");
            }
        }

        /// <summary>
        /// Zgłasza kuchni nowe zamówienie
        /// </summary>
        /// <param name="zamowienie">zamówienie do przekazania</param>
        /// <param name="kuchnia">obecnie pracująca osoba w kuchni</param>
        public void PowiadomKuchnie(Zamowienie zamowienie, Kuchnia kuchnia)
        {
            kuchnia.PrzyjmijZamowienie(zamowienie);
        }

        /// <summary>
        /// Dodaje potrawy do istniejacego zamowienia
        /// </summary>
        /// <param name="potrawaDoUsuniecia">Lista potraw do dodania</param>
        /// <param name="zamowienie">Aktualizowane zamówienie</param>
        public void DodajPotrawy(Dictionary<Potrawa, int> potrawyDoDodania, Zamowienie zamowienie)
        {
            try
            {
                using (RestauracjaContext context = new RestauracjaContext())
                {
                    foreach (var potrawa in potrawyDoDodania)
                    {
                        ZamowieniaPotrawy zampotr = new ZamowieniaPotrawy();
                        zampotr.Id = ZamowieniaPotrawy.PobierzWolneId(context);
                        zampotr.CzyWydana = (int)ZamowieniePotrawaStatus.KelnerZlecilDoKuchni;
                        zampotr.IdPotrawy = potrawa.Key.Id;
                        zampotr.IdZamowienia = zamowienie.Id;
                        zampotr.Ilosc = potrawa.Value;
                        context.ZamowieniaPotrawy.Add(zampotr);
                    }

                    //Wszystkie propertiesy są przypisywane- inaczej nie działa update :(
                    zamowienie.Status = (int)zamowienie.Status;
                    zamowienie.Cena += (decimal)potrawyDoDodania.Sum(x => x.Key.Cena * x.Value);
                    zamowienie.data = zamowienie.data;
                    zamowienie.NrStolika = zamowienie.NrStolika;
                    zamowienie.Id = zamowienie.Id;

                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Wystapił błąd przy zmianie dodawaniu potraw do zamówienia");
            }
        }

        /// <summary>
        /// Usuwa potrawe z zamowienia
        /// </summary>
        /// <param name="zamowienie">Zamowienie z ktorego ma zostac usunieta potrawa</param>
        /// <param name="potrawyDoUsuniecia">Potrway ktore maja byc usuniete, ich ilosc</param>
        public void UsunPotrawy(Dictionary<Potrawa, int> potrawyDoUsuniecia, Zamowienie zamowienie)
        {
            try
            {
                using (RestauracjaContext context = new RestauracjaContext())
                {
                    foreach (var potrawa in potrawyDoUsuniecia)
                    {
                        ZamowieniaPotrawy zampotr = context.ZamowieniaPotrawy.Where(zampot =>
                            zampot.IdPotrawy == potrawa.Key.Id &&
                            zampot.IdZamowienia == zamowienie.Id).FirstOrDefault();

                        if (zampotr == null)
                        {
                            MessageBox.Show("Nie znaleziono potrawy: \"" + potrawa.Key.Nazwa + "\" w tym zamówieniu");
                        }
                        else if (zampotr != null)
                        {
                            if (potrawa.Value >= zampotr.Ilosc)
                            {
                                context.ZamowieniaPotrawy.Remove(zampotr);

                                //Wszystkie propertiesy są przypisywane- inaczej nie działa update :(
                                zamowienie.Status = (int)zamowienie.Status;
                                zamowienie.Cena -= (decimal)(zampotr.Ilosc * potrawa.Key.Cena);
                                zamowienie.data = zamowienie.data;
                                zamowienie.NrStolika = zamowienie.NrStolika;
                                zamowienie.Id = zamowienie.Id;
                            }
                            else
                            {
                                //Wszystkie propertiesy są przypisywane- inaczej nie działa update :(
                                zampotr.Id = zampotr.Id;
                                zampotr.CzyWydana = zampotr.CzyWydana;
                                zampotr.IdPotrawy = zampotr.IdPotrawy;
                                zampotr.IdZamowienia = zampotr.IdZamowienia;
                                zampotr.Ilosc = zampotr.Ilosc - potrawa.Value;

                                //Wszystkie propertiesy są przypisywane- inaczej nie działa update :(
                                zamowienie.Status = (int)zamowienie.Status;
                                zamowienie.Cena -= (decimal)(zampotr.Ilosc * potrawa.Key.Cena);
                                zamowienie.data = zamowienie.data;
                                zamowienie.NrStolika = zamowienie.NrStolika;
                                zamowienie.Id = zamowienie.Id;
                            }

                            context.SaveChanges();
                        }
                    }
                }
            }
            catch (Exception)
            {
                MessageBox.Show("Wystapił błąd przy usuwaniu potraw z zamówienia");
            }
        }

        /// <summary>
        /// Zmienia status potrawy na wydaną
        /// </summary>
        /// <param name="potrawa">Potrawa do wydania</param>
        /// <param name="zamowienie">Zamowienie w którym znajduje się potrawa</param>
        public void WydajKlientowiPosilek(Potrawa potrawa, Zamowienie zamowienie)
        {
            try
            {
                using (RestauracjaContext context = new RestauracjaContext())
                {
                    var zamowionaPotrawa = context.ZamowieniaPotrawy
                        .Where(zampot => zampot.IdPotrawy == potrawa.Id &&
                                         zampot.IdZamowienia == zamowienie.Id && 
                                         zampot.CzyWydana == (int)ZamowieniePotrawaStatus.KuchniaZlecilaDoKelnera).FirstOrDefault();

                    zamowionaPotrawa.CzyWydana = (int)ZamowieniePotrawaStatus.KelnerWydalKlientowi;
                    zamowionaPotrawa.Id = zamowionaPotrawa.Id;
                    zamowionaPotrawa.IdPotrawy = zamowionaPotrawa.IdPotrawy;
                    zamowionaPotrawa.IdZamowienia = zamowionaPotrawa.IdZamowienia;
                    zamowionaPotrawa.Ilosc = zamowionaPotrawa.Ilosc;

                    context.SaveChanges();
                }
            }
            catch (Exception)
            {
                MessageBox.Show("Wystapił błąd przy wydawaniu klientowi posilku");
            }
        }

        /// <summary>
        /// Usuwa wybrane zamowienie
        /// </summary>
        /// <param name="zamowienie">zamowienie do usuniecia</param>
        public void UsunZamowienie(Zamowienie zamowienie)
        {
            try
            {
                using (RestauracjaContext context = new RestauracjaContext())
                {
                    Zamowienie zamowienieDoUsuniecia = context.Zamowienia.First(zam => zam.Id == zamowienie.Id);
                    context.Zamowienia.Remove(zamowienieDoUsuniecia);

                    var zampotDoUsuniecia = context.ZamowieniaPotrawy.Where(zampot => zampot.IdZamowienia == zamowienie.Id).ToList();

                    foreach (var zampot in zampotDoUsuniecia)
                        context.ZamowieniaPotrawy.Remove(zampot);

                    context.SaveChanges();
                }
            }
            catch (Exception)
            {
                MessageBox.Show("Wystapił błąd przy usuwaniu zamowienia");
            }
        }

        #endregion Methods
    }
}
